"""场景检测视图模块"""
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel,
                             QPushButton, QComboBox, QSpinBox, QDoubleSpinBox,
                             QGroupBox, QCheckBox, QProgressBar, QMessageBox)
from PyQt6.QtCore import Qt, QThread, pyqtSignal
from src.ui.styles import (BUTTON_STYLE, INPUT_STYLE, LABEL_STYLE,
                      PROGRESS_BAR_STYLE, MESSAGEBOX_STYLE, GROUP_BOX_STYLE,
                      COMBO_BOX_STYLE, CHECK_BOX_STYLE)
from src.video_processor import VideoProcessor, SceneInfo

class SceneDetectionWorker(QThread):
    progress_updated = pyqtSignal(int)
    detection_finished = pyqtSignal(list)
    error_occurred = pyqtSignal(str)
    
    def __init__(self, video_path, threshold, min_scene_length, algorithm="smart", extra_params=None):
        super().__init__()
        self.video_path = video_path
        self.threshold = threshold
        self.min_scene_length = min_scene_length
        self.algorithm = algorithm
        self.extra_params = extra_params if extra_params else {}
        
    def run(self):
        try:
            processor = VideoProcessor()
            if not processor.load_video(self.video_path):
                self.error_occurred.emit("无法加载视频文件")
                return
                
            # 获取视频信息
            video_info = processor.get_video_info()
            total_frames = video_info["total_frames"]
            fps = video_info["fps"]
            
            # 将最小场景长度（秒）转换为帧数
            min_scene_length_frames = int(self.min_scene_length * fps)
            
            # 检测场景
            scenes = processor.detect_scenes(
                threshold=self.threshold,
                min_scene_length=min_scene_length_frames,
                algorithm=self.algorithm,
                progress_callback=lambda p: self.progress_updated.emit(int(p * 100)),
                **self.extra_params
            )
            
            # 发送检测完成信号
            self.detection_finished.emit(scenes)
            
        except Exception as e:
            self.error_occurred.emit(str(e))
        finally:
            processor.release()

class SceneDetectionView(QWidget):
    """场景检测视图类"""
    
    # 自定义信号
    detection_started = pyqtSignal()  # 检测开始信号
    detection_finished = pyqtSignal(list)  # 检测完成信号，参数为场景列表
    scenes_detected = pyqtSignal(list)
    back_requested = pyqtSignal()  # 新增返回信号
    
    def __init__(self):
        super().__init__()
        self.setWindowTitle("场景检测")
        self.video_path = None  # 初始化video_path属性
        self._init_ui()
        self._apply_styles()
        
    def _init_ui(self):
        """初始化UI组件"""
        # 创建主布局
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(24, 24, 24, 24)
        main_layout.setSpacing(24)
        
        # 算法选择组
        algorithm_group = QGroupBox("检测算法")
        algorithm_layout = QVBoxLayout(algorithm_group)
        algorithm_layout.setContentsMargins(18, 18, 18, 18)
        algorithm_layout.setSpacing(18)
        
        # 算法选择下拉框
        algorithm_label = QLabel("选择算法:")
        self.algorithm_combo = QComboBox()
        self.algorithm_combo.addItems([
            "智能分镜 (推荐)",
            "帧差法",
            "直方图法",
            "内容变化法",
            "混合策略"
        ])
        self.algorithm_combo.currentIndexChanged.connect(self._on_algorithm_changed)
        
        algorithm_layout.addWidget(algorithm_label)
        algorithm_layout.addWidget(self.algorithm_combo)
        
        # 参数设置组
        params_group = QGroupBox("参数设置")
        params_layout = QVBoxLayout(params_group)
        params_layout.setContentsMargins(18, 18, 18, 18)
        params_layout.setSpacing(18)
        
        # 阈值设置
        threshold_layout = QHBoxLayout()
        threshold_label = QLabel("检测阈值:")
        self.threshold_spin = QDoubleSpinBox()
        self.threshold_spin.setRange(0.1, 1.0)
        self.threshold_spin.setSingleStep(0.1)
        self.threshold_spin.setValue(0.5)
        threshold_layout.addWidget(threshold_label)
        threshold_layout.addWidget(self.threshold_spin)
        threshold_layout.addStretch()
        
        # 最小场景长度设置
        min_scene_layout = QHBoxLayout()
        min_scene_label = QLabel("最小场景长度(秒):")
        self.min_scene_spin = QSpinBox()
        self.min_scene_spin.setRange(1, 60)
        self.min_scene_spin.setValue(3)
        min_scene_layout.addWidget(min_scene_label)
        min_scene_layout.addWidget(self.min_scene_spin)
        min_scene_layout.addStretch()
        
        # 智能分镜特有参数
        self.smart_params_group = QGroupBox("智能分镜参数")
        smart_params_layout = QVBoxLayout(self.smart_params_group)
        smart_params_layout.setContentsMargins(18, 18, 18, 18)
        smart_params_layout.setSpacing(18)
        
        # 特征权重设置
        weights_layout = QHBoxLayout()
        weights_label = QLabel("特征权重:")
        self.visual_weight_spin = QDoubleSpinBox()
        self.visual_weight_spin.setRange(0.1, 1.0)
        self.visual_weight_spin.setSingleStep(0.1)
        self.visual_weight_spin.setValue(0.4)
        self.visual_weight_spin.setPrefix("视觉: ")
        
        self.motion_weight_spin = QDoubleSpinBox()
        self.motion_weight_spin.setRange(0.1, 1.0)
        self.motion_weight_spin.setSingleStep(0.1)
        self.motion_weight_spin.setValue(0.3)
        self.motion_weight_spin.setPrefix("运动: ")
        
        self.audio_weight_spin = QDoubleSpinBox()
        self.audio_weight_spin.setRange(0.1, 1.0)
        self.audio_weight_spin.setSingleStep(0.1)
        self.audio_weight_spin.setValue(0.3)
        self.audio_weight_spin.setPrefix("音频: ")
        
        weights_layout.addWidget(weights_label)
        weights_layout.addWidget(self.visual_weight_spin)
        weights_layout.addWidget(self.motion_weight_spin)
        weights_layout.addWidget(self.audio_weight_spin)
        weights_layout.addStretch()
        
        smart_params_layout.addLayout(weights_layout)
        
        # 添加所有参数到主布局
        params_layout.addLayout(threshold_layout)
        params_layout.addLayout(min_scene_layout)
        
        main_layout.addWidget(algorithm_group)
        main_layout.addWidget(params_group)
        main_layout.addWidget(self.smart_params_group)
        
        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        main_layout.addWidget(self.progress_bar)
        
        # 检测按钮
        button_layout = QHBoxLayout()
        button_layout.setContentsMargins(0, 0, 0, 0)
        button_layout.setSpacing(10)
        
        self.detect_btn = QPushButton("开始检测")
        self.detect_btn.clicked.connect(self._start_detection)
        button_layout.addStretch()
        button_layout.addWidget(self.detect_btn)
        
        main_layout.addLayout(button_layout)
        
        # 初始化时隐藏智能分镜参数
        self.smart_params_group.setVisible(False)
        
    def _apply_styles(self):
        """应用喜马拉雅风格全局样式"""
        self.setStyleSheet(f"""
            {LABEL_STYLE}
            {BUTTON_STYLE}
            {INPUT_STYLE}
            {PROGRESS_BAR_STYLE}
            {GROUP_BOX_STYLE}
            {COMBO_BOX_STYLE}
            {CHECK_BOX_STYLE}
        """)
        
    def _on_algorithm_changed(self, index):
        """算法选择改变事件"""
        # 显示/隐藏智能分镜参数
        self.smart_params_group.setVisible(index == 0)
        
        # 更新阈值范围
        if index == 0:  # 智能分镜
            self.threshold_spin.setRange(0.1, 1.0)
            self.threshold_spin.setValue(0.5)
        elif index == 1:  # 帧差法
            self.threshold_spin.setRange(10.0, 100.0)
            self.threshold_spin.setValue(30.0)
        elif index == 2:  # 直方图法
            self.threshold_spin.setRange(0.1, 1.0)
            self.threshold_spin.setValue(0.3)
        elif index == 3:  # 内容变化法
            self.threshold_spin.setRange(10.0, 100.0)
            self.threshold_spin.setValue(50.0)
        elif index == 4:  # 混合策略
            self.threshold_spin.setRange(0.1, 1.0)
            self.threshold_spin.setValue(0.5)
            
    def _start_detection(self):
        """开始场景检测"""
        if not self.video_path:
            msg = QMessageBox(self)
            msg.setIcon(QMessageBox.Icon.Warning)
            msg.setWindowTitle("警告")
            msg.setText("请先选择视频文件")
            msg.setStyleSheet(MESSAGEBOX_STYLE)
            msg.exec()
            return
            
        # 禁用按钮
        self.detect_btn.setEnabled(False)
        
        # 显示进度条
        self.progress_bar.setVisible(True)
        self.progress_bar.setValue(0)
        
        # 获取算法参数
        algorithm_index = self.algorithm_combo.currentIndex()
        algorithm_map = {
            0: "smart",    # 智能分镜
            1: "diff",     # 帧差法
            2: "hist",     # 直方图法
            3: "content",  # 内容变化法
            4: "hybrid"    # 混合策略
        }
        algorithm = algorithm_map[algorithm_index]
        
        # 获取额外参数
        extra_params = {}
        if algorithm == "smart":
            extra_params = {
                "weights": {
                    "visual": self.visual_weight_spin.value(),
                    "motion": self.motion_weight_spin.value(),
                    "audio": self.audio_weight_spin.value()
                }
            }
        
        # 创建并启动检测线程
        self.worker = SceneDetectionWorker(
            self.video_path,
            self.threshold_spin.value(),
            self.min_scene_spin.value(),
            algorithm,
            extra_params
        )
        
        # 连接信号
        self.worker.progress_updated.connect(self.update_progress)
        self.worker.detection_finished.connect(self._on_detection_finished)
        self.worker.error_occurred.connect(self._on_error)
        
        # 启动线程
        self.worker.start()
        
    def update_progress(self, value):
        """更新进度条"""
        self.progress_bar.setValue(value)
        
    def _on_detection_finished(self, scenes):
        """检测完成处理"""
        # 启用按钮
        self.detect_btn.setEnabled(True)
        
        # 隐藏进度条
        self.progress_bar.setVisible(False)
        
        # 发送检测完成信号
        self.scenes_detected.emit(scenes)
        
    def _on_error(self, error_msg):
        """错误处理"""
        self.detect_btn.setEnabled(True)
        self.progress_bar.setVisible(False)
        
        msg = QMessageBox(self)
        msg.setIcon(QMessageBox.Icon.Critical)
        msg.setWindowTitle("错误")
        msg.setText(f"检测过程中发生错误：{error_msg}")
        msg.setStyleSheet(MESSAGEBOX_STYLE)
        msg.exec()
        
    def set_video_path(self, path):
        """设置视频路径"""
        self.video_path = path 